package net.mikoo.seals.boss.biz.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import net.mikoo.seals.boss.biz.mapper.boss.MenuMapper;
import net.mikoo.seals.boss.biz.mapper.boss.PartyMapper;
import net.mikoo.seals.boss.biz.mapper.boss.RolePermitMapper;
import net.mikoo.seals.boss.common.enums.PartyStatusEnum;
import net.mikoo.seals.boss.common.enums.PartyTypeEnum;
import net.mikoo.seals.boss.model.Menu;
import net.mikoo.seals.boss.model.MenuQuery;
import net.mikoo.seals.boss.model.Party;

/**
 * User userdetail该类实现 UserDetails 接口，该类在验证成功后会被保存在当前回话的principal对象中
 * 
 * 获得对象的方式：
 * WebUserDetails webUserDetails = (WebUserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
 * 
 * 或在JSP中：
 * <sec:authentication property="principal.username"/>
 * 
 * 如果需要包括用户的其他属性，可以实现 UserDetails 接口中增加相应属性即可
 * 权限验证类
 * @author lanyuan
 * 2013-11-19
 * @Email: mmm333zzz520@163.com
 * @version 1.0v
 */
@Service
public class MyUserDetailServiceImpl implements UserDetailsService {
	
	private Logger logger  = Logger.getLogger(MyUserDetailServiceImpl.class);
	
	@Autowired
	private PartyMapper partyMapper;
	
	@Autowired
	private RolePermitMapper rolePermitMapper;
	
	@Autowired
	private MenuMapper menuMapper;
	
	// 登录验证
	public UserDetails loadUserByUsername(String userLoginId) throws UsernameNotFoundException {
//		System.err.println("-----------MyUserDetailServiceImpl loadUserByUsername ----------- ");
		
		//取得用户的权限
		Party party = partyMapper.selectByUserLoginId(userLoginId, PartyTypeEnum.OPERATOR.code());
		if (party == null) {
			throw new UsernameNotFoundException(userLoginId + " not exist!");
		}
		Collection<GrantedAuthority> grantedAuths = obtionGrantedAuthorities(party);
		
		boolean enabled = false;
        boolean expired = party.nonExpired();
        String partyStatus = party.getPartyStatus();
        if(partyStatus.equals(PartyStatusEnum.NORMAL.code())){
        	enabled = true;
        }
		
		// 封装成spring security的user
		User userdetail = new User(
				party.getUserLoginId(), 
				party.getUserLogin().getCurrentPassword(),
				enabled,  //账号状态  0 表示停用  1表示启用
				expired, 
				true,
				true, 
				grantedAuths	//用户的权限
			);
		return userdetail;
	}

	// 取得用户的权限
	private Set<GrantedAuthority> obtionGrantedAuthorities(Party party) {
		
		Long partyId = party.getPartyId();

		List<Menu> menus = new ArrayList<Menu>();
		if (partyId.intValue() == 1) {
			
			MenuQuery query= new MenuQuery();
			query.setIsEnable("Y");
			menus = menuMapper.selectListByQuery(query);
		} else {
			menus = rolePermitMapper.selectHaveResource(partyId);
		}
		
		
		Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>();
		for (Menu menu : menus) {
			// TODO:ZZQ 用户可以访问的资源名称（或者说用户所拥有的权限） 注意：必须"ROLE_"开头
			// 关联代码：applicationContext-security.xml
			// 关联代码：com.huaxin.security.MySecurityMetadataSource#loadResourceDefine
			logger.info(menu.getMenuName()+":"+menu.getActions());
			authSet.add(new SimpleGrantedAuthority("ROLE_" + menu.getMenuCode()));
		}
		return authSet;
		
	}
}